package org.epidroid.epidroid.chronos.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.epidroid.epidroid.chronos.engine.Chronos;
import org.epidroid.epidroid.chronos.engine.exceptions.ChronosException;
import org.epidroid.epidroid.chronos.engine.objects.ChronosCalendar;
import org.epidroid.epidroid.chronos.engine.objects.ChronosDay;
import org.epidroid.epidroid.chronos.engine.objects.ChronosNode;
import org.epidroid.epidroid.chronos.engine.objects.ChronosWeek;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class ChronosService extends Service implements IChronosService {

	private static String[] CATEGORIES = { "rooms", "trainnees", "instructors" };

	private Chronos _chronos = null;

	// TODO: remove static everywhere and set as a service...
	private HashMap<String, ChronosWeek> _mapWeeks = null;
	private HashMap<String, ChronosDay> _mapDays = null;
	private ChronosNode _menus = null;
	private List<ChronosNode> _favorites = null;
	private ChronosServiceBinder _binder = null;

	@Override
	public void onCreate() {
		_mapWeeks = new HashMap<String, ChronosWeek>();
		_mapDays = new HashMap<String, ChronosDay>();
		_favorites = new ArrayList<ChronosNode>();

		_chronos = new Chronos();
		_binder = new ChronosServiceBinder(this);
		super.onCreate();
	}

	@Override
	public IBinder onBind(Intent arg0) {
		return _binder;
	}

	private String getWeekKey(int week, String group) {
		return week + group;
	}

	private String getDayKey(int week, int day, String group) {
		return week + group + day;
	}

	/*
	 * Return the information concerning a day.
	 * 
	 * @param week the id of the week
	 * 
	 * @param day the id of the day (Monday = 1, Tuesday = 2, ...)
	 */
	public ChronosDay getDay(int week, int day, String group)
			throws ChronosException {

		/* First, retrieve the corresponding week */
		ChronosWeek w = getWeek(week, group);
		if (null == w)
			throw new ChronosException("Could not find the corresponding week");
		if (w.getDays().size() <= day)
			throw new ChronosException("Could not find the day in the week");

		ChronosDay res = w.getDays().get(day);

		/* Add the day in the corresponding map for later use */
		_mapDays.put(getDayKey(week, day, group), res);
		if (week == -1) {
			_mapDays.put(getDayKey(Integer.valueOf(w.getId()), day, group), res);
		}

		return res;
	}

	public ChronosNode getMenu(String name) {
		if (_menus != null) {
			return _menus;
		}
		ChronosNode node = _chronos.getMenu(name);
		_menus = node;
		return node;
	}

	public ChronosWeek getWeek(int week, String group) throws ChronosException {
		String key = getWeekKey(week, group);
		ChronosWeek w = _mapWeeks.get(key);

		if (null == w) {
			ChronosCalendar c = getWeeks(week, group, 1);
			if ((null == c) || (c.getWeeks().size() == 0))
				return null;
			w = c.getWeeks().get(0);
		}

		return w;
	}

	public ChronosCalendar getWeeks(int week, String group, int num)
			throws ChronosException {

		ChronosCalendar calendar = _chronos.getWeeks(week, group, num);

		for (ChronosWeek w : calendar.getWeeks()) {
			_mapWeeks.put(getWeekKey(Integer.valueOf(w.getId()), group), w);
		}

		if ((week == -1) && (calendar.getWeeks().size() > 0)) {
			_mapWeeks.put(getWeekKey(-1, group), calendar.getWeeks().get(0));
		}

		return calendar;
	}

	@Override
	public void setFavorite(ChronosNode node) {
		_favorites.add(node);
	}

	@Override
	public void unsetFavorite(ChronosNode node) {
		_favorites.remove(node);
	}

	@Override
	public List<ChronosNode> getFavorites() {
		return _favorites;
	}

	@Override
	public boolean isFav(ChronosNode node) {
		return _favorites.contains(node);
	}
}
